package com.huiyun.project.im.api.biz.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.huiyun.project.base.controller.BaseController;
import com.huiyun.project.common.core.domain.R;
import com.huiyun.project.common.core.util.fn.FunctionUtils;
import com.huiyun.project.common.sequence.IdUtils;
import com.huiyun.project.im.api.client.vo.req.app.ImAppReq;
import com.huiyun.project.im.api.client.vo.req.tenant.ImTenantsReq;
import com.huiyun.project.im.api.client.vo.req.tenant.ImUserCsReq;
import com.huiyun.project.im.api.client.vo.req.user.ImUserReq;
import com.huiyun.project.im.api.client.vo.resp.ImAppResp;
import com.huiyun.project.im.api.client.vo.resp.ImTenantResp;
import com.huiyun.project.im.api.client.vo.resp.ImUserResp;
import com.huiyun.project.im.common.auth.AppPrincipal;
import com.huiyun.project.im.common.auth.SecurityUtils;
import com.huiyun.project.im.consts.ImServerConst;
import com.huiyun.project.im.consts.ImTenantConst;
import com.huiyun.project.im.consts.ImUserConst;
import com.huiyun.project.im.core.dto.ImTenantDto;
import com.huiyun.project.im.core.service.IImAppService;
import com.huiyun.project.im.core.service.IImTenantService;
import com.huiyun.project.im.core.service.IImUserService;
import com.huiyun.project.im.entity.ImApp;
import com.huiyun.project.im.entity.ImTenant;
import com.huiyun.project.im.entity.ImUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.wf.jwtp.annotation.Logical;
import org.wf.jwtp.annotation.RequiresRoles;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @FileName:ApiImSpController
 * @Description: 提供给服务商的接口
 * @Author linjie
 * @Date 2020/7/1711:19 AM
 * @Version 4.0.0
 */
@RestController
@RequestMapping("im/api/sp/{version}")
@AllArgsConstructor
@Api(tags = "开发服务商集成")
public class ApiSpController extends BaseController {

    private final IImTenantService tenantService;

    private final IImAppService appService;

    private final IImUserService userService;

    /**
     * 批量创建im账户 企业租户
     * 会创建一个普通账户
     *
     * @param imTenantList
     * @return
     */
    @PostMapping("/tenants")
    @ApiOperation("批量创建或者修改租户,APP_GROUP_ID+BID唯一")
    @RequiresRoles({ImServerConst.API_SP_ROLE})
    public R<List<ImTenantResp>> tenants(@Validated @RequestBody List<ImTenantsReq> imTenantList) {
        return FunctionUtils.wrapper(() -> {
            List<ImTenant> tenantList = new ArrayList<>();
            ImTenant imTenant;
            Date now = new Date();
            AppPrincipal principal = SecurityUtils.getAppPrincipal();
            for (ImTenantsReq req : imTenantList) {
                imTenant = new ImTenant();
                imTenant.setId(String.valueOf(IdUtils.getId()));
                imTenant.setBid(req.getBid());
                imTenant.setLogo(req.getLogo());
                imTenant.setName(req.getName());
                imTenant.setTenantType(req.getTenantType() == null ? ImTenantConst.TENANT_TYPE_1 : req.getTenantType());
                imTenant.setTenantCate(req.getTenantCate());
                imTenant.setCreateBy(principal.getId());
                imTenant.setCreateTime(now);
                imTenant.setModifyBy(principal.getId());
                imTenant.setModifyTime(now);
                tenantList.add(imTenant);
            }
            List<ImTenantDto> dtoList = tenantService.saveOrUpdateTenant(tenantList);
            return R.ok(tenantDtoToResp(dtoList));
        });
    }

    @PostMapping("/users/{tenantId}")
    @ApiOperation("创建或者修改租户下账号,APP_GROUP_ID+USERNAME唯一")
    @RequiresRoles({ImServerConst.API_SP_ROLE})
    public R<List<ImUserResp>> tenantUsers(@PathVariable("tenantId") String tenantId, @RequestBody List<ImUserReq> imUserList) {
        return FunctionUtils.wrapper(() -> {
            List<ImUser> list = new ArrayList<>();
            ImUser imUser;
            AppPrincipal principal = SecurityUtils.getAppPrincipal();
            for (ImUserReq userReq : imUserList) {
                imUser = buildImUser(tenantId, principal, userReq);
                list.add(imUser);
            }
            List<ImUser> result = userService.saveOrUpdateTenantUser(list);
            return R.ok(userToResp(result));
        });
    }

    private ImUser buildImUser(String tenantId, AppPrincipal principal, ImUserReq userReq) {
        ImUser imUser = new ImUser();
        Date now = new Date();
        String appId = principal.getId().startsWith(ImServerConst.APP_STORE_PREFIX) ? principal.getId().split(":")[1] : principal.getId();
        //普通账号
        imUser.setType(userReq.getType() == null ? ImUserConst.TYPE.TYPE_1.getValue() : userReq.getType());
        imUser.setId(String.valueOf(IdUtils.getId()));
        imUser.setUsername(userReq.getUsername());
        imUser.setPassword(userReq.getPassword());
        imUser.setAvatar(userReq.getAvatar());
        imUser.setNick(userReq.getNick());
        imUser.setAlias(userReq.getAlias());
        imUser.setSalt(userReq.getSalt());

        imUser.setUserOrgId(StrUtil.isNotBlank(userReq.getUserOrgId()) ? userReq.getUserOrgId() : ImUserConst.USER_ORG_0);

        imUser.setCreateBy(appId);
        imUser.setCreateTime(now);
        imUser.setModifyTime(now);
        imUser.setModifyBy(appId);
        imUser.setBid(userReq.getBid());
        imUser.setImTenantId(tenantId);
        imUser.setImSpId(principal.getImSpId());
        imUser.setAppGroupId(principal.getAppGroupId());
        imUser.setAppId(appId);
        return imUser;
    }

    /**
     * C端用户修改或者创建
     *
     * @param userReq
     * @return
     */
    @PostMapping("/user")
    @ApiOperation("单个创建或者修改客户账号")
    @RequiresRoles({ImServerConst.API_SP_ROLE})
    public R<ImUserResp> user(@Validated @RequestBody ImUserReq userReq) {
        return FunctionUtils.wrapper(() -> {
            //1.构建一个个人租户
            //2.构建一个用户
            //3.存储
            Date now = new Date();
            AppPrincipal principal = SecurityUtils.getAppPrincipal();
            ImTenant imTenant = new ImTenant();
            imTenant.setId(String.valueOf(IdUtils.getId()));
            imTenant.setLogo(userReq.getAvatar());
            imTenant.setBid(userReq.getBid());
            imTenant.setName(userReq.getNick());
            imTenant.setTenantType(ImTenantConst.TENANT_TYPE_0);
            imTenant.setTenantCate(ImTenantConst.CATE_4);
            imTenant.setCreateBy(principal.getId());
            imTenant.setCreateTime(now);
            imTenant.setModifyBy(principal.getId());
            imTenant.setModifyTime(now);

            //普通账号
            ImUser imUser = new ImUser();
            imUser.setType(ImUserConst.TYPE.TYPE_1.getValue());
            imUser.setId(String.valueOf(IdUtils.getId()));
            imUser.setUsername(userReq.getUsername());
            imUser.setPassword(userReq.getPassword());
            imUser.setSalt(userReq.getSalt());
            imUser.setNick(userReq.getNick());
            imUser.setAlias(userReq.getNick());

            imUser.setAvatar(userReq.getAvatar());
            imUser.setUserOrgId(ImUserConst.USER_ORG_0);
            imUser.setCreateBy(principal.getAppId());
            imUser.setCreateTime(now);
            imUser.setModifyTime(now);
            imUser.setModifyBy(principal.getAppId());

            imUser.setBid(userReq.getBid());
            imUser.setImTenantId(imTenant.getId());
            imUser.setImSpId(principal.getImSpId());
            imUser.setAppGroupId(principal.getAppGroupId());
            imUser.setAppId(principal.getAppId());
            userService.saveOrUpdateUser(imTenant, imUser);
            return R.ok(new ImUserResp()
                    .setAppGroupId(imUser.getAppGroupId())
                    .setAppKey(principal.getAppKey())
                    .setBid(imUser.getBid())
                    .setImTenantId(imTenant.getId())
                    .setUserOrgId(imUser.getUserOrgId())
            );
        });
    }


    /**
     * 客服授权账号修改等
     *
     * @param tenantId
     * @param req
     * @return
     */
    @PostMapping("/user/cs/{tenantId}")
    @ApiOperation("客服账号增加或修改")
    @RequiresRoles(value = {ImServerConst.API_SP_ROLE}, logical = Logical.OR)
    public R updateUserCs(@PathVariable("tenantId") String tenantId, @RequestBody ImUserCsReq req) {
        return FunctionUtils.wrapper(() -> {
            AppPrincipal principal = SecurityUtils.getAppPrincipal();
            ImUser imUser = buildImUser(tenantId, principal, req.getUser());
            userService.updateUserCs(req.getGrantType(), imUser);
            return R.ok(userToResp(Lists.newArrayList(imUser)));
        });
    }


    @PostMapping("/delete/{tenantId}")
    @ApiOperation("子账号删除")
    @RequiresRoles(value = {ImServerConst.API_SP_ROLE, ImServerConst.API_TENANT_ROLE}, logical = Logical.OR)
    public R deleteUsers(@PathVariable("tenantId") String tenantId, @RequestBody List<String> bidList) {
        return FunctionUtils.wrapper(() -> {
            if (CollectionUtil.isNotEmpty(bidList)) {
                return R.ok(userService.deleteTenantUserByBid(bidList, tenantId));
            }
            return R.ok();
        });
    }
    //####################################################

    @GetMapping("/tenant/tenants")
    @ApiOperation("租户查询")
    @RequiresRoles({ImServerConst.API_SP_ROLE})
    public R tenants(Long page, Long limit) {
        return FunctionUtils.wrapper(() -> {
            return R.ok();
        });

    }


    @DeleteMapping("/tenant/delete/{tenantId}")
    @ApiOperation("租户删除")
    @RequiresRoles({ImServerConst.API_SP_ROLE})
    public R delete(@PathVariable String tenantId) {
        return FunctionUtils.wrapper(() -> {
            return R.ok();
        });

    }


    @PostMapping("/tenant/disable/{tenantId}")
    @ApiOperation("租户禁用")
    @RequiresRoles({ImServerConst.API_SP_ROLE})
    public R disable(@PathVariable String tenantI) {
        return FunctionUtils.wrapper(() -> {
            return R.ok();
        });

    }


    @PostMapping("/tenant/enable/{tenantId}")
    @ApiOperation("租户启用")
    @RequiresRoles({ImServerConst.API_SP_ROLE})
    public R enable(@PathVariable String tenantI) {
        return FunctionUtils.wrapper(() -> {
            return R.ok();
        });
    }


    @PostMapping("/tenant/subs")
    @ApiOperation("创建或者修改子账户")
    @RequiresRoles({ImServerConst.API_SP_ROLE})
    public R sub(@RequestBody List<ImTenantsReq> subs) {
        return FunctionUtils.wrapper(() -> {
            return R.ok();
        });
    }


    @PostMapping("/app")
    @ApiOperation("创建或者修改应用")
    @RequiresRoles({ImServerConst.API_SP_ROLE})
    public R app(@RequestBody Object app) {
        return FunctionUtils.wrapper(() -> {
            return R.ok();
        });
    }


    @PostMapping("/app_group")
    @ApiOperation("创建或者修改应用组")
    @RequiresRoles({ImServerConst.API_SP_ROLE})
    public R appGroup() {
        return FunctionUtils.wrapper(() -> {
            return R.ok();
        });
    }


    /**
     * 租户聊天记录查询
     *
     * @return
     */
    @GetMapping("/chat/msg")
    @ApiOperation("聊天记录查询")
    @RequiresRoles({ImServerConst.API_TENANT_ROLE})
    public R chatMsg() {
        return FunctionUtils.wrapper(() -> {
            //限制只能查当前租户
            return R.ok();
        });
    }


    @PostMapping("/report/chat")
    @ApiOperation("消息统计")
    @RequiresRoles({ImServerConst.API_SP_ROLE})
    public R reportChat() {
        return FunctionUtils.wrapper(() -> {
            return R.ok();
        });
    }


    @PostMapping("/report/tenant")
    @ApiOperation("统计租户")
    @RequiresRoles({ImServerConst.API_SP_ROLE})
    public R reportTenant() {
        return FunctionUtils.wrapper(() -> {
            return R.ok();
        });
    }


    @PostMapping("/report/user")
    @ApiOperation("统计用户")
    @RequiresRoles({ImServerConst.API_SP_ROLE})
    public R reportUser() {
        return FunctionUtils.wrapper(() -> {
            return R.ok();
        });
    }


    @PostMapping("/app/getByAppKey")
    @ApiOperation("获取应用信息")
    @RequiresRoles({ImServerConst.API_SP_ROLE})
    public R<ImAppResp> getByAppKey(@Validated @RequestBody ImAppReq imAppReq) {
        return FunctionUtils.wrapper(() -> {
            ImApp imApp = appService.findByAppKey(imAppReq.getAppKey());
            ImAppResp resp = new ImAppResp();
            resp.setAppGroupId(imApp.getAppGroupId());
            resp.setName(imApp.getName());
            resp.setType(imApp.getType());
            return R.ok(resp);
        });
    }

    private List<ImUserResp> userToResp(List<ImUser> list) {
        List<ImUserResp> respList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(list)) {
            ImUserResp resp;
            for (ImUser imUser : list) {
                resp = new ImUserResp();
                BeanUtil.copyProperties(imUser, resp);
                //用户Id也返回
                resp.setImUserId(imUser.getId());
                respList.add(resp);
            }
        }
        return respList;
    }

    private List<ImTenantResp> tenantDtoToResp(List<ImTenantDto> list) {
        List<ImTenantResp> respList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(list)) {
            ImTenantResp resp;
            for (ImTenantDto dto : list) {
                resp = new ImTenantResp();
                BeanUtil.copyProperties(dto, resp);
                resp.setImTenantId(dto.getId());
                respList.add(resp);
            }
        }
        return respList;
    }
}
